﻿' This sample code is courtesy of http://www.gotreportviewer.com

Imports System.Collections.Generic
Imports System.Text
Imports System.Xml
Imports System.Data
Imports System.Data.SqlClient
Imports System.IO
Imports System.Windows.Forms
Imports Microsoft.Reporting.WinForms

Namespace RdlViewer
    ''' <summary>
    ''' Think of this class as a "Reflector for RDL". It digs into the XML refinition of the RDL and
    ''' extracts useful information.
    ''' </summary>
    Public Class clsReportInfo
        Private m_rdlFilename As String
        Private m_dataSourceDictionary As Dictionary(Of String, DataSourceInfo)
        Private m_dataSetDictionary As Dictionary(Of String, DataSetInfo)
        Private m_reportParmList As List(Of ReportParmInfo)

        Public Sub New(rdlFilename As String)
            Me.m_rdlFilename = rdlFilename
        End Sub

        Public ReadOnly Property DataSources As Dictionary(Of String, DataSourceInfo)
            Get
                Return m_dataSourceDictionary
            End Get
        End Property

        Public ReadOnly Property DataSets As Dictionary(Of String, DataSetInfo)
            Get
                Return m_dataSetDictionary
            End Get
        End Property

        Public ReadOnly Property ReportParameters As List(Of ReportParmInfo)
            Get
                Return m_reportParmList
            End Get
        End Property

        Private Sub ExtractReferencedDataSourceInfo(dataSourceName As String, dataSourceReference As String)
            Dim rdsDocument As New XmlDocument()
            Dim rdsFilename As String = Path.GetDirectoryName(m_rdlFilename) & "\" & dataSourceReference & ".rds"
            rdsDocument.Load(rdsFilename)

            Dim connectionPropsNode As XmlNode = rdsDocument.SelectSingleNode("RptDataSource/ConnectionProperties")
            Dim connectStringNode As XmlNode = connectionPropsNode.SelectSingleNode("ConnectString")
            Dim connectString As String = connectStringNode.InnerText
            m_dataSourceDictionary.Add(dataSourceName, New DataSourceInfo(connectString))
        End Sub

        Private Sub ExtractDataSourceInfo(rdlDocument As XmlDocument, nsmgr As XmlNamespaceManager)
            m_dataSourceDictionary = New Dictionary(Of String, DataSourceInfo)()

            Dim dataSourcesNode As XmlNode = rdlDocument.SelectSingleNode("r:Report/r:DataSources", nsmgr)
            If dataSourcesNode Is Nothing Then
                Return
            End If
            Dim dataSourceList As XmlNodeList = dataSourcesNode.SelectNodes("r:DataSource", nsmgr)
            For Each dataSourceNode As XmlNode In dataSourceList
                Dim dataSourceName As String = dataSourceNode.Attributes.GetNamedItem("Name").InnerText
                Dim connectionPropsNode As XmlNode = dataSourceNode.SelectSingleNode("r:ConnectionProperties", nsmgr)
                If connectionPropsNode Is Nothing Then
                    Dim dataSourceReferenceNode As XmlNode = dataSourceNode.SelectSingleNode("r:DataSourceReference", nsmgr)
                    Dim dataSourceReference As String = dataSourceReferenceNode.InnerText
                    ExtractReferencedDataSourceInfo(dataSourceName, dataSourceReference)
                Else
                    Dim connectStringNode As XmlNode = connectionPropsNode.SelectSingleNode("r:ConnectString", nsmgr)
                    Dim connectString As String = connectStringNode.InnerText
                    m_dataSourceDictionary.Add(dataSourceName, New DataSourceInfo(connectString))
                End If
            Next
        End Sub

        Private Sub ExtractDataSetInfo(rdlDocument As XmlDocument, nsmgr As XmlNamespaceManager)
            m_dataSetDictionary = New Dictionary(Of String, DataSetInfo)()

            Dim dataSetsNode As XmlNode = rdlDocument.SelectSingleNode("r:Report/r:DataSets", nsmgr)
            If dataSetsNode Is Nothing Then
                Return
            End If
            Dim dataSetList As XmlNodeList = dataSetsNode.SelectNodes("r:DataSet", nsmgr)
            For Each dataSetNode As XmlNode In dataSetList
                Dim dataSetName As String = dataSetNode.Attributes.GetNamedItem("Name").InnerText
                Dim queryNode As XmlNode = dataSetNode.SelectSingleNode("r:Query", nsmgr)
                Dim dataSourceNameNode As XmlNode = queryNode.SelectSingleNode("r:DataSourceName", nsmgr)
                Dim dataSourceName As String = dataSourceNameNode.InnerText
                Dim commandTextNode As XmlNode = queryNode.SelectSingleNode("r:CommandText", nsmgr)
                Dim commandText As String = commandTextNode.InnerText

                Dim parametersNode As XmlNode = queryNode.SelectSingleNode("r:QueryParameters", nsmgr)
                Dim queryParameters As IList(Of QueryParameterInfo) = Nothing
                If parametersNode IsNot Nothing Then
                    queryParameters = New List(Of QueryParameterInfo)()
                    Dim parameterList As XmlNodeList = parametersNode.SelectNodes("r:QueryParameter", nsmgr)
                    For Each parameterNode As XmlNode In parameterList
                        Dim parameterName As String = parameterNode.Attributes.GetNamedItem("Name").InnerText
                        Dim valueNode As XmlNode = parameterNode.SelectSingleNode("r:Value", nsmgr)
                        Dim valueExpression As String = valueNode.InnerText
                        Dim queryParameterInfo As New QueryParameterInfo(parameterName, valueExpression)
                        queryParameters.Add(queryParameterInfo)
                    Next
                End If

                Dim filtersNode As XmlNode = queryNode.SelectSingleNode("r:Filters", nsmgr)
                Dim queryFilters As IList(Of QueryFilterInfo) = Nothing
                If filtersNode IsNot Nothing Then
                    queryFilters = New List(Of QueryFilterInfo)
                    Dim filterList As XmlNodeList = parametersNode.SelectNodes("r:Filter", nsmgr)
                    For Each filterNode As XmlNode In filterList
                        Dim expressionNode As XmlNode = filterNode.SelectSingleNode("r:FilterExpression", nsmgr)
                        Dim expression As String = expressionNode.InnerText
                        Dim operatorNode As XmlNode = filterNode.SelectSingleNode("r:Operator", nsmgr)
                        Dim [operator] As String = operatorNode.InnerText
                        Dim queryfilterInfo As New QueryFilterInfo(expression, [operator])
                        queryFilters.Add(queryfilterInfo)
                    Next
                End If

                Dim dataSetInfo As New DataSetInfo(dataSourceName, commandText)
                dataSetInfo.queryParameters = queryParameters
                dataSetInfo.queryFilters = queryFilters
                m_dataSetDictionary.Add(dataSetName, dataSetInfo)
            Next
        End Sub

        Private Sub ExtractReportParmInfo(rdldocument As XmlDocument, nsmgr As XmlNamespaceManager)
            m_reportParmList = New List(Of ReportParmInfo)()

            Dim reportparmsnode As XmlNode = rdldocument.SelectSingleNode("r:Report/r:ReportParameters", nsmgr)
            If reportparmsnode Is Nothing Then
                Return
            End If
            Dim reportparmlist As XmlNodeList = reportparmsnode.SelectNodes("r:ReportParameter", nsmgr)
            For Each reportparmnode As XmlNode In reportparmlist

                Dim reportparmname As String = reportparmnode.Attributes.GetNamedItem("Name").InnerText

                Dim datatype As String = reportparmnode.SelectSingleNode("r:DataType", nsmgr).InnerText

                Dim multivaluenode As XmlNode = reportparmnode.SelectSingleNode("r:MultiValue", nsmgr)
                Dim multivalue As String = False
                If multivaluenode IsNot Nothing Then multivalue = reportparmnode.SelectSingleNode("r:MultiValue", nsmgr).InnerText

                Dim lstdefaults As New List(Of String)
                Dim defaultvaluenode As XmlNode = reportparmnode.SelectSingleNode("r:DefaultValue", nsmgr)
                If defaultvaluenode IsNot Nothing Then
                    Dim defaultvaluelist As XmlNodeList = defaultvaluenode.SelectNodes("r:Values", nsmgr)
                    For Each valuenode As XmlNode In defaultvaluelist
                        lstdefaults.Add(valuenode.InnerText)
                    Next
                End If

                Dim prompt As String = reportparmnode.SelectSingleNode("r:Prompt", nsmgr).InnerText

                Dim validvaluesnode As XmlNode = reportparmnode.SelectSingleNode("r:ValidValues", nsmgr)

                Dim lstdataset As New List(Of ParmDatasetInfo)
                Dim dictparameter As New Generic.Dictionary(Of String, String)

                If validvaluesnode IsNot Nothing Then
                    Dim datasetlist As XmlNodeList = validvaluesnode.SelectNodes("r:DataSetReference", nsmgr)
                    For Each datasetnode As XmlNode In datasetlist
                        Dim datasetname As String = datasetnode.SelectSingleNode("r:DataSetName", nsmgr).InnerText
                        Dim valuefield As String = datasetnode.SelectSingleNode("r:ValueField", nsmgr).InnerText
                        Dim labelfield As String = datasetnode.SelectSingleNode("r:LabelField", nsmgr).InnerText
                        lstdataset.Add(New ParmDatasetInfo(datasetname, valuefield, labelfield))
                    Next

                    Dim parametervaluesnode As XmlNode = validvaluesnode.SelectSingleNode("r:ParameterValues", nsmgr)
                    If parametervaluesnode IsNot Nothing Then
                        Dim parameterlist As XmlNodeList = parametervaluesnode.SelectNodes("r:ParameterValue", nsmgr)
                        For Each parameternode As XmlNode In parameterlist
                            Dim value As String = parameternode.SelectSingleNode("r:Value", nsmgr).InnerText
                            Dim label As String = parameternode.SelectSingleNode("r:Label", nsmgr).InnerText
                            dictparameter.Add(value, label)
                        Next
                    End If
                End If

                Dim reportparminfo As New ReportParmInfo(reportparmname, prompt, datatype, lstdefaults, lstdataset, multivalue, dictparameter)
                m_reportParmList.Add(reportparminfo)
            Next
        End Sub

        Public Sub Initialize()
            Dim rdlDocument As New XmlDocument()
            rdlDocument.Load(m_rdlFilename)

            Dim root As XmlElement = rdlDocument.DocumentElement

            Dim nsmgr As New XmlNamespaceManager(rdlDocument.NameTable)
            nsmgr.AddNamespace("r", root.NamespaceURI)
            nsmgr.AddNamespace("rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner")

            ExtractDataSourceInfo(rdlDocument, nsmgr)
            ExtractDataSetInfo(rdlDocument, nsmgr)
            ExtractReportParmInfo(rdlDocument, nsmgr)
        End Sub

        'Public Function GetData(dataSetName As String, reportParams As ReportParameterInfoCollection) As DataTable
        '    Dim dataSetInfo As DataSetInfo = m_dataSetDictionary(dataSetName)
        '    If dataSetInfo.dataTable Is Nothing Then
        '        Dim dataSourceInfo As DataSourceInfo = m_dataSourceDictionary(dataSetInfo.dataSourceName)
        '        Dim command As SqlCommand = dataSourceInfo.connection.CreateCommand()
        '        command.CommandText = dataSetInfo.query
        '        If dataSetInfo.queryParameters IsNot Nothing Then
        '            For Each queryParameterInfo As QueryParameterInfo In dataSetInfo.queryParameters
        '                Dim valueExpression As String = queryParameterInfo.valueExpression
        '                Const starting As String = "=Parameters!"
        '                Const ending As String = ".Value"
        '                If Not valueExpression.StartsWith(starting) OrElse Not valueExpression.EndsWith(ending) Then
        '                    Throw New Exception("Can't parse query parameter expression: " & valueExpression)
        '                End If
        '                Dim parameterNameLen As Integer = valueExpression.Length - starting.Length - ending.Length
        '                Dim parameterName As String = valueExpression.Substring(starting.Length, parameterNameLen)

        '                If reportParams IsNot Nothing Then
        '                    Dim reportParameterValue As String = reportParams(parameterName).Values(0)

        '                    If reportParameterValue Is Nothing Then
        '                        Throw New Exception("Report parameter " & parameterName & " has no value set")
        '                    End If

        '                    Dim ReportParameterValueObj As Object = Nothing
        '                    Try
        '                        Select Case reportParams(parameterName).DataType
        '                            Case ParameterDataType.Boolean : ReportParameterValueObj = CBool(reportParameterValue)
        '                            Case ParameterDataType.DateTime : ReportParameterValueObj = CDate(reportParameterValue)
        '                            Case ParameterDataType.Float : ReportParameterValueObj = CDbl(reportParameterValue)
        '                            Case ParameterDataType.Integer : ReportParameterValueObj = CInt(reportParameterValue)
        '                            Case ParameterDataType.String : ReportParameterValueObj = reportParameterValue
        '                        End Select
        '                    Catch ex As Exception
        '                        ReportParameterValueObj = DBNull.Value
        '                    End Try

        '                    command.Parameters.AddWithValue(queryParameterInfo.parameterName, ReportParameterValueObj)
        '                End If
        '            Next
        '        End If

        '        Dim reader As SqlDataReader = command.ExecuteReader()
        '        Dim dataTable As New DataTable()
        '        dataTable.Load(reader)
        '        reader.Close()

        '        dataSetInfo.dataTable = dataTable
        '    End If
        '    Return dataSetInfo.dataTable
        'End Function

        ''' <summary>
        ''' This is the delegate for the routine that will be passed as an address
        ''' </summary>
        ''' <param name="reportParams"></param>
        ''' <returns></returns>
        Public Delegate Function GetDataTable(reportParams As ReportParameterCollection) As Boolean
        Public Property GetDataTableMethod As GetDataTable = Nothing

        ''' <summary>
        ''' Retrieve data from WRDB into datatable specified by the indicated dataset; if getting records for temp data table, add Selected_By clause
        ''' </summary>
        ''' <param name="dataSetName"></param>
        ''' <param name="reportParams"></param>
        ''' <param name="Project"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetData(dataSetName As String, reportParams As ReportParameterInfoCollection, Project As Project.clsProject) As DataTable
            Dim dataSetInfo As DataSetInfo = m_dataSetDictionary(dataSetName)
            If True Or dataSetInfo.dataTable Is Nothing Then
                Dim dataSourceInfo As DataSourceInfo = m_dataSourceDictionary(dataSetInfo.dataSourceName)
                If dataSourceInfo.connection Is Nothing Then
                    dataSourceInfo.connection = Project.DB.Connection
                    Project.DB.OpenConnection()
                End If
                Dim command As Common.DbCommand = dataSourceInfo.connection.CreateCommand()

                'SQL may contain comments which must be removed
                command.CommandText = ""
                For Each s In dataSetInfo.query.Split(vbNewLine)
                    If String.IsNullOrEmpty(s) OrElse s.StartsWith("--") Then
                        s = ""
                    Else
                        Dim j As Integer = s.IndexOf("--")
                        If j <> -1 Then s = s.Substring(0, j - 1).Trim
                    End If
                    command.CommandText &= " " & s.Replace(vbCr, "").Replace(vbLf, "")
                Next

                'command.CommandText = dataSetInfo.query.Replace(vbCrLf, " ").Replace(vbCr, " ").Replace(vbLf, " ")

                'see if getting data from temp table; if so automatically revise the statement to only query this user's records
                'oops! I got confused; originally I used ShowAllOwnerRecords to indicate whether should only get records "Selected_By..."
                'but they don't have anything to do with each other!

                Dim lstSQL As New Generic.List(Of String)
                lstSQL.AddRange(command.CommandText.ToUpper.Split(New Char() {" "}, StringSplitOptions.RemoveEmptyEntries))
                If lstSQL.Contains(WRDB.Project.clsProject.TempData.ToUpper) Then
                    'if ORDER clause, need to insert before
                    Dim idxOrder As Integer = command.CommandText.Length
                    If lstSQL.Contains("ORDER") Then idxOrder = command.CommandText.ToUpper.IndexOf("ORDER")

                    If lstSQL.Contains("WHERE") Then
                        command.CommandText = command.CommandText.Insert(idxOrder, String.Format(" AND Selected_By='{0}' ", WRDB.Project.clsApplicationSettings.UserName))
                    Else
                        command.CommandText = command.CommandText.Insert(idxOrder, String.Format(" WHERE Selected_By='{0}' ", WRDB.Project.clsApplicationSettings.UserName))
                    End If
                End If

                If dataSetInfo.queryParameters IsNot Nothing Then
                    For Each queryParameterInfo As QueryParameterInfo In dataSetInfo.queryParameters
                        Dim valueExpression As String = queryParameterInfo.valueExpression
                        Const starting As String = "=Parameters!"
                        Const ending As String = ".Value"
                        If Not valueExpression.StartsWith(starting) OrElse Not valueExpression.EndsWith(ending) Then
                            Throw New Exception("Can't parse query parameter expression: " & valueExpression)
                        End If
                        Dim parameterNameLen As Integer = valueExpression.Length - starting.Length - ending.Length
                        Dim parameterName As String = valueExpression.Substring(starting.Length, parameterNameLen)
                        Dim reportParameterValue As String = Nothing
                        If reportParams(parameterName).Values.Count > 0 Then reportParameterValue = reportParams(parameterName).Values(0)

                        If reportParameterValue Is Nothing Then
                            reportParameterValue = ""
                            'Throw New Exception("Report parameter " & parameterName & " has no value set")
                        End If

                        Select Case Project.DB.DatabaseType
                            Case DBProviders.clsDB.enumDBType.SQL_Server, DBProviders.clsDB.enumDBType.SQL_Server_CE
                                Dim ReportParameterValueObj As Object = Nothing
                                Try
                                    Select Case reportParams(parameterName).DataType
                                        Case ParameterDataType.Boolean : ReportParameterValueObj = CBool(reportParameterValue)
                                        Case ParameterDataType.DateTime : ReportParameterValueObj = CDate(reportParameterValue)
                                        Case ParameterDataType.Float : ReportParameterValueObj = CDbl(reportParameterValue)
                                        Case ParameterDataType.Integer : ReportParameterValueObj = CInt(reportParameterValue)
                                        Case ParameterDataType.String : ReportParameterValueObj = reportParameterValue
                                    End Select
                                Catch ex As Exception
                                    ReportParameterValueObj = DBNull.Value
                                End Try
                                CType(command, SqlCommand).Parameters.AddWithValue(queryParameterInfo.parameterName, ReportParameterValueObj)
                            Case Else
                                WarningMsg("Parameters are allowed in the report design only for SQL Server databases.")
                                Return Nothing
                        End Select
                    Next
                End If

                Dim reader As Common.DbDataReader = command.ExecuteReader()
                Dim dataTable As New DataTable()
                dataTable.Load(reader)
                reader.Close()

                dataSetInfo.dataTable = dataTable
            End If
            Return dataSetInfo.dataTable
        End Function

        '''' <summary>
        '''' Retrieve data from WRDB into datatable specified by the indicated dataset; 
        '''' This version is called by WRDBWeb application where a dataset has already been filled with selected records
        '''' </summary>
        '''' <param name="dataSetName"></param>
        '''' <param name="reportParams"></param>
        '''' <param name="Project"></param>
        '''' <returns></returns>
        '''' <remarks>If report designed to pull records from TempData, will substitute SelectedData table from dataset</remarks>
        'Public Function GetData(dataSetName As String, reportParams As ReportParameterInfoCollection, Project As Project.clsProject, WebDataSet As DataSet) As DataTable
        '    Dim dataSetInfo As DataSetInfo = m_dataSetDictionary(dataSetName)
        '    If dataSetInfo.dataTable Is Nothing Then
        '        Dim dataSourceInfo As DataSourceInfo = m_dataSourceDictionary(dataSetInfo.dataSourceName)
        '        If dataSourceInfo.connection Is Nothing Then
        '            dataSourceInfo.connection = Project.DB.Connection
        '            Project.DB.OpenConnection()
        '        End If
        '        Dim command As Common.DbCommand = dataSourceInfo.connection.CreateCommand()
        '        command.CommandText = dataSetInfo.query

        '        'see if getting data from temp table; if so automatically replace with selected records

        '        Dim lstSQL As New Generic.List(Of String)
        '        lstSQL.AddRange(command.CommandText.ToUpper.Split(New Char() {" "}, StringSplitOptions.RemoveEmptyEntries))

        '        'get tablename from SQL; assume it follows FROM keyword
        '        Dim tablename As String = ""
        '        If lstSQL.Contains("FROM") Then
        '            tablename = lstSQL(lstSQL.IndexOf("FROM") + 1)
        '        Else
        '            Throw New Exception("Unable to parse SQL string in report to determine table: " & command.CommandText)
        '        End If

        '        Dim dataTable As DataTable = Nothing

        '        If dataSetInfo.queryParameters Is Nothing Then 'no built in query parameters so is simple select of all records
        '            If tablename = WRDB.Project.clsProject.TempData.ToUpper Then
        '                dataTable = WebDataSet.Tables("SelectedData")
        '            ElseIf WebDataSet.Tables.Contains(tablename) Then
        '                dataTable = WebDataSet.Tables(tablename)
        '            Else 'not in dataset, get from database
        '                Dim reader As Common.DbDataReader = command.ExecuteReader()
        '                dataTable = New DataTable()
        '                dataTable.Load(reader)
        '                reader.Close()
        '            End If
        '        Else 'because has parameters, MUST query from database
        '            If tablename = WRDB.Project.clsProject.TempData.ToUpper Then
        '                Throw New Exception("This report was designed with query parameters but also queries from the TempData table, which is not allowed in the WRDBWeb application.")
        '            End If
        '            For Each queryParameterInfo As QueryParameterInfo In dataSetInfo.queryParameters
        '                Dim valueExpression As String = queryParameterInfo.valueExpression
        '                Const starting As String = "=Parameters!"
        '                Const ending As String = ".Value"
        '                If Not valueExpression.StartsWith(starting) OrElse Not valueExpression.EndsWith(ending) Then
        '                    Throw New Exception("Can't parse query parameter expression: " & valueExpression)
        '                End If
        '                Dim parameterNameLen As Integer = valueExpression.Length - starting.Length - ending.Length
        '                Dim parameterName As String = valueExpression.Substring(starting.Length, parameterNameLen)
        '                Dim reportParameterValue As String = reportParams(parameterName).Values(0)

        '                If reportParameterValue Is Nothing Then
        '                    Throw New Exception("Report parameter " & parameterName & " has no value set")
        '                End If

        '                Select Case Project.DB.DatabaseType
        '                    Case DBProviders.clsDB.enumDBType.SQL_Server, DBProviders.clsDB.enumDBType.SQL_Server_CE
        '                        Dim ReportParameterValueObj As Object = Nothing
        '                        Try
        '                            Select Case reportParams(parameterName).DataType
        '                                Case ParameterDataType.Boolean : ReportParameterValueObj = CBool(reportParameterValue)
        '                                Case ParameterDataType.DateTime : ReportParameterValueObj = CDate(reportParameterValue)
        '                                Case ParameterDataType.Float : ReportParameterValueObj = CDbl(reportParameterValue)
        '                                Case ParameterDataType.Integer : ReportParameterValueObj = CInt(reportParameterValue)
        '                                Case ParameterDataType.String : ReportParameterValueObj = reportParameterValue
        '                            End Select
        '                        Catch ex As Exception
        '                            ReportParameterValueObj = DBNull.Value
        '                        End Try
        '                        CType(command, SqlCommand).Parameters.AddWithValue(queryParameterInfo.parameterName, ReportParameterValueObj)
        '                    Case Else
        '                        Throw New Exception("Parameters are allowed in the report design only for SQL Server databases.")
        '                End Select
        '            Next
        '            Dim reader As Common.DbDataReader = command.ExecuteReader()
        '            dataTable = New DataTable()
        '            dataTable.Load(reader)
        '            reader.Close()
        '        End If

        '        dataSetInfo.dataTable = dataTable
        '    End If
        '    Return dataSetInfo.dataTable
        'End Function

        Public Sub Cleanup()
            For Each dataSourceInfo As DataSourceInfo In m_dataSourceDictionary.Values
                If dataSourceInfo.connection IsNot Nothing Then
                    dataSourceInfo.connection.Close()
                End If
            Next
            m_dataSourceDictionary = Nothing
            m_dataSetDictionary = Nothing
        End Sub
    End Class

    Public Class DataSetInfo
        Public dataSourceName As String
        Public query As String
        Public dataTable As DataTable
        Public queryParameters As IList(Of QueryParameterInfo)
        Public queryFilters As IList(Of QueryParameterInfo)

        Public Sub New(dataSourceName As String, query As String)
            Me.dataSourceName = dataSourceName
            Me.query = query
        End Sub
    End Class

    Public Class QueryParameterInfo
        Public parameterName As String
        Public valueExpression As String

        Public Sub New(parameterName As String, valueExpression As String)
            Me.parameterName = parameterName
            Me.valueExpression = valueExpression
        End Sub
    End Class

    Public Class QueryFilterInfo
        Public expression As String
        Public [operator] As String
        Public values As List(Of String)

        Public Sub New(expression As String, [operator] As String)
            Me.expression = expression
            Me.operator = [operator]
        End Sub
    End Class

    Public Class DataSourceInfo
        Public connectString As String
        Public connection As Common.DbConnection

        Public Sub New(connectString As String)
            Me.connectString = connectString
        End Sub
    End Class

    Public Class ReportParmInfo
        Public Name As String
        Public Prompt As String
        Public DataType As String
        Public Defaults As List(Of String)
        Public Datasets As List(Of ParmDatasetInfo)
        Public MultiValue As Boolean = False
        Public Parameters As Dictionary(Of String, String)
        Public Value As String 'the value assigned by the user
        Public Sub New(parameterName As String, prompt As String, dataType As String, Defaults As Generic.List(Of String), Datasets As List(Of ParmDatasetInfo), MultiValue As Boolean, Parameters As Dictionary(Of String, String))
            Me.Name = parameterName
            Me.Prompt = prompt
            Me.DataType = dataType
            Me.Defaults = Defaults
            Me.Datasets = Datasets
            Me.MultiValue = MultiValue
            Me.Parameters = Parameters
        End Sub
    End Class

    Public Class ParmDatasetInfo
        Public datasetName As String
        Public fields As New Dictionary(Of String, String)
        Public Sub New(datasetName As String, valueField As String, labelField As String)
            Me.datasetName = datasetName
            Me.fields.Add(valueField, labelField)
        End Sub
    End Class

End Namespace
